package com.hyk.commonLib.common.utils;

import android.text.TextUtils;

import org.apache.commons.lang3.StringUtils;

import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 贺玉琨 on 2019/6/4.
 */

public class ValidateUtils {
    //邮箱表达式
    private final static Pattern EMAIL_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");

    //手机号表达式
    private final static Pattern PHONE_PATTERN = Pattern.compile("^1\\d{10}$");

    //银行卡号表达式
    private final static Pattern BANK_NO_PATTERN = Pattern.compile("^[0-9]{16,19}$");

    //座机号码表达式
    private final static Pattern PLANE_PATTERN = Pattern.compile("^((\\(\\d{2,3}\\))|(\\d{3}-))?(\\(0\\d{2,3}\\)|0\\d{2,3}-)?[1-9]\\d{6,7}(-\\d{1,4})?$");

    //数字表达式
    private final static Pattern NUMBER_PATTERN = Pattern.compile("^[0-9]*$");

    //大写字母表达式
    private final static Pattern UP_CHAR_PATTERN = Pattern.compile("^[A-Z]+$");

    //小写字母表达式
    private final static Pattern LOW_CHAR_PATTERN = Pattern.compile("^[a-z]+$");

    //大小写字母表达式
    private final static Pattern LETTER_PATTERN = Pattern.compile("^[A-Za-z]+$");

    //中文汉字表达式
    private final static Pattern CHINESE_PATTERN = Pattern.compile("^[\u4e00-\u9fa5],*$");

    //邮政编码表达式
    private final static Pattern POSTALCODE_PATTERN = Pattern.compile("([0-9]{3})+.([0-9]{4})+");

    //IP地址表达式
    private final static Pattern IP_ADDRESS_PATTERN = Pattern.compile("[1-9](\\d{1,2})?\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))");

    //URL地址表达式
    private final static Pattern URL_PATTERN = Pattern.compile("(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?");

    //真实姓名表达式
    private final static Pattern REAL_NAME_PATTERN = Pattern.compile("[\u4E00-\u9FA5]{2,5}(?:·[\u4E00-\u9FA5]{2,5})*");

    /**
     * 验证是数字
     *
     * @param str 验证字符
     * @return boolean
     */
    public static boolean isNumber(String str) {
        if (StringUtils.isEmpty(str)) return false;
        return NUMBER_PATTERN.matcher(str).matches();
    }


    /**
     * 验证是大写字母
     *
     * @param str 验证字符
     * @return boolean
     */
    public static boolean isUpChar(String str) {
        if (StringUtils.isEmpty(str)) return false;
        return UP_CHAR_PATTERN.matcher(str).matches();
    }


    /**
     * 验证是小写字母
     *
     * @param str 验证字符
     * @return boolean
     */
    public static boolean isLowChar(String str) {
        if (StringUtils.isEmpty(str)) return false;
        return LOW_CHAR_PATTERN.matcher(str).matches();
    }


    /**
     * 验证是英文字母
     *
     * @param str 验证字符
     * @return boolean
     */
    public static boolean isLetter(String str) {
        if (StringUtils.isEmpty(str)) return false;
        return LETTER_PATTERN.matcher(str).matches();
    }


    /**
     * 验证输入汉字
     *
     * @param str 验证字符
     * @return boolean
     */
    public static boolean isChinese(String str) {
        if (StringUtils.isEmpty(str)) return false;
        return CHINESE_PATTERN.matcher(str).matches();
    }


    /**
     * 验证真实姓名
     *
     * @param str 验证字符
     * @return boolean
     */
    public static boolean isRealName(String str) {
        if (StringUtils.isEmpty(str)) return false;
        return REAL_NAME_PATTERN.matcher(str).matches();
    }

    /**
     * 验证邮箱是否正确
     *
     * @param email 邮箱地址
     * @return boolean
     */
    public static boolean isEmail(String email) {
        if (StringUtils.isEmpty(email)) return false;
        return EMAIL_PATTERN.matcher(email).matches();
    }


    /**
     * 验证手机号是否正确
     *
     * @param phone 手机号码
     * @return boolean
     */
    public static boolean isPhone(String phone) {
        if (StringUtils.isEmpty(phone)) return false;
        return PHONE_PATTERN.matcher(phone).matches();
    }


    /**
     * 验证座机号码是否正确
     *
     * @param plane 座机号码
     * @return boolean
     */
    public static boolean isPlane(String plane) {
        if (StringUtils.isEmpty(plane)) return false;
        return PLANE_PATTERN.matcher(plane).matches();
    }

    /**
     * 验证邮政编码是否正确
     *
     * @param postalcode 邮政编码
     * @return boolean
     */
    public static boolean isPostalCode(String postalcode) {
        if (StringUtils.isEmpty(postalcode)) return false;
        return POSTALCODE_PATTERN.matcher(postalcode).matches();
    }


    /**
     * 验证IP地址是否正确
     *
     * @param ipaddress IP地址
     * @return boolean
     */
    public static boolean isIpAddress(String ipaddress) {
        if (StringUtils.isEmpty(ipaddress)) return false;
        return IP_ADDRESS_PATTERN.matcher(ipaddress).matches();
    }

    /**
     * 验证URL地址是否正确
     *
     * @param url 地址
     * @return boolean
     */
    public static boolean isURL(String url) {
        if (StringUtils.isEmpty(url)) return false;
        return URL_PATTERN.matcher(url).matches();
    }

    /**
     * 验证是否是整数
     *
     * @param str 验证字符
     * @return boolean
     */
    public static boolean isInteger(String str) {
        if (StringUtils.isEmpty(str)) return false;
        try {
            Integer.valueOf(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 验证是否是小数
     *
     * @param paramString 验证字符
     * @return boolean
     */
    public static boolean isPoint(String paramString) {
        if (StringUtils.isEmpty(paramString)) return false;
        if (paramString.indexOf(".") > 0) {
            if (paramString.substring(paramString.indexOf(".")).length() > 3) {
                return false;
            }
        }
        return true;
    }


    /**
     * 验证是否银行卡号
     *
     * @param bankNo 银行卡号
     * @return
     */
    public static boolean isBankNo(String bankNo) {
        if (StringUtils.isEmpty(bankNo)) return false;
        //替换空格
        bankNo = bankNo.replaceAll(" ", "");
        //银行卡号可为12位数字
        if (12 == bankNo.length()) {
            return true;
        }
        //银行卡号可为16-19位数字
        return BANK_NO_PATTERN.matcher(bankNo).matches();
    }


    /**
     * 描述：是否包含中文.
     *
     * @param str 指定的字符串
     * @return 是否包含中文:是为true，否则false
     */
    public static boolean isContainChinese(String str) {
        if (StringUtils.isEmpty(str)) return false;
        boolean isChinese = false;
        String chinese = "[\u0391-\uFFE5]";
        if (!TextUtils.isEmpty(str)) {
            // 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
            for (int i = 0; i < str.length(); i++) {
                // 获取一个字符
                String temp = str.substring(i, i + 1);
                // 判断是否为中文字符
                if (temp.matches(chinese)) {
                    isChinese = true;
                }
            }
        }
        return isChinese;
    }

    /**
     * 描述：ip地址转换为10进制数.
     *
     * @param ip the ip
     * @return the long
     */
    public static long ip2int(String ip) {
        ip = ip.replace(".", ",");
        String[] items = ip.split(",");
        return Long.parseLong(items[0]) << 24 | Long.parseLong(items[1]) << 16
                | Long.parseLong(items[2]) << 8 | Long.parseLong(items[3]);
    }

    /**
     * 获取UUID
     *
     * @return 32UUID小写字符串
     */
    public static String gainUUID() {
        String strUUID = UUID.randomUUID().toString();
        strUUID = strUUID.replaceAll("-", "").toLowerCase();
        return strUUID;
    }


    /**
     * 手机号码，中间4位星号替换
     *
     * @param phone 手机号
     * @return 星号替换的手机号
     */
    public static String phoneNoHide(String phone) {
        // 括号表示组，被替换的部分$n表示第n组的内容
        // 正则表达式中，替换字符串，括号的意思是分组，在replace()方法中，
        // 参数二中可以使用$n(n为数字)来依次引用模式串中用括号定义的字串。
        // "(\d{3})\d{4}(\d{4})", "$1****$2"的这个意思就是用括号，
        // 分为(前3个数字)中间4个数字(最后4个数字)替换为(第一组数值，保持不变$1)(中间为*)(第二组数值，保持不变$2)
        return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    /**
     * 银行卡号，保留最后4位，其他星号替换
     *
     * @param cardId 卡号
     * @return 星号替换的银行卡号
     */
    public static String cardIdHide(String cardId) {
        return cardId.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1");
    }

    /**
     * 身份证号，中间10位星号替换
     *
     * @param id 身份证号
     * @return 星号替换的身份证号
     */
    public static String idHide(String id) {
        return id.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2");
    }

    /**
     * 是否为车牌号（沪A88888）
     *
     * @param vehicleNo 车牌号
     * @return 是否为车牌号
     */

    public static boolean checkVehicleNo(String vehicleNo) {
        Pattern pattern = Pattern.compile("^[\u4e00-\u9fa5][a-zA-Z][a-zA-Z_0-9]{5}$");
        return pattern.matcher(vehicleNo).find();

    }

    /**
     * 判断字符串是否为连续数字 45678901等
     *
     * @param str 待验证的字符串
     * @return 是否为连续数字
     */
    public static boolean isContinuousNum(String str) {
        if (TextUtils.isEmpty(str))
            return false;
        if (!isNumber(str))
            return true;
        int len = str.length();
        for (int i = 0; i < len - 1; i++) {
            char curChar = str.charAt(i);
            char verifyChar = (char) (curChar + 1);
            if (curChar == '9')
                verifyChar = '0';
            char nextChar = str.charAt(i + 1);
            if (nextChar != verifyChar) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否是纯字母
     *
     * @param str 待验证的字符串
     * @return 是否是纯字母
     */
    public static boolean isAlphaBetaString(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }

        Pattern p = Pattern.compile("^[a-zA-Z]+$");// 从开头到结尾必须全部为字母或者数字
        Matcher m = p.matcher(str);

        return m.find();
    }

    /**
     * 判断字符串是否为连续字母 xyZaBcd等
     *
     * @param str 待验证的字符串
     * @return 是否为连续字母
     */
    public static boolean isContinuousWord(String str) {
        if (TextUtils.isEmpty(str))
            return false;
        if (!isAlphaBetaString(str))
            return true;
        int len = str.length();
        String local = str.toLowerCase();
        for (int i = 0; i < len - 1; i++) {
            char curChar = local.charAt(i);
            char verifyChar = (char) (curChar + 1);
            if (curChar == 'z')
                verifyChar = 'a';
            char nextChar = local.charAt(i + 1);
            if (nextChar != verifyChar) {
                return false;
            }
        }
        return true;
    }
}




